package com.ruoyi.prt.service.impl;

import com.alibaba.fastjson.JSON;
import com.ruoyi.common.constant.EqpStatus;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.vo.WebSocketVO;
import com.ruoyi.common.utils.MessageUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.ehcache.EqpStatusCache;
import com.ruoyi.prt.domain.PrtEpLog;
import com.ruoyi.prt.domain.PrtEqp;
import com.ruoyi.prt.domain.PrtPriceMode;
import com.ruoyi.prt.domain.PrtPrintLog;
import com.ruoyi.prt.domain.vo.PrtCouponVO;
import com.ruoyi.prt.service.*;
import com.ruoyi.system.service.ISysUserService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;

/**
 * @author huangziliang
 * @version 1.0
 * @date 2021/4/12 0:28
 */
@Service
public class PrtPrintServiceImpl implements IPrtPrintService {

    @Autowired
    private IPrtEqpService prtEqpService;

    @Autowired
    private IPrtPriceModeService prtPriceModeService;

    @Autowired
    private IPrtCouponService prtCouponService;

    @Autowired
    private ISysUserService sysUserService;

    @Autowired
    private IPrtPrintLogService prtPrintLogService;

    @Autowired
    private IPrtEpLogService iPrtEpLogService;

    @Override
    public AjaxResult checkCanPrint(WebSocketVO params) {
        //0.校验打印页数
        String page = params.getPage();
        if (StringUtils.isEmpty(page)) {
            return AjaxResult.error(MessageUtils.message("prt.print.page.null"));
        }
        //1.计算打印价格
        AjaxResult calcPrice = calcPrice(params);
        if (calcPrice.isError()) {
            return calcPrice;
        }
        PrtCouponVO priceData = (PrtCouponVO) calcPrice.getData();
        //2.判断余额是否充足
        SysUser sysUser = sysUserService.selectUserById(params.getUserId());
        if (sysUser == null) {
            return AjaxResult.error(MessageUtils.message("prt.usr.notfound"));
        }
        if (sysUser.getBalance().compareTo(priceData.getPayPrice()) < 0) {
            return AjaxResult.error(MessageUtils.message("prt.print.balance.no", priceData.getPageNum()
                    , priceData.getOncePrice(), priceData.getOriginalPrice(), priceData.getPrice(), priceData.getPayPrice()));
        }
        //3.判断打印机状态是否可以打印
        if (EqpStatusCache.getEqpStatus(params.getEqpName()) != EqpStatus.CONNECTED) {
            return AjaxResult.error(MessageUtils.message("prt.ws.printer.busy"));
        }
        return AjaxResult.success(MessageUtils.message("prt.print.check.pass", priceData.getPageNum()
                , priceData.getOncePrice(), priceData.getOriginalPrice(), priceData.getPrice(), priceData.getPayPrice()), priceData);
    }

    @Override
    public String splitPrintPrams(WebSocketVO params) {
        return JSON.toJSONString(params);
    }

    @Override
    @Transactional(rollbackFor = {RuntimeException.class, Exception.class}, isolation = Isolation.SERIALIZABLE)
    public AjaxResult deductionBalance(SysUser sysUser, WebSocketVO webSocketVO) {
        BigDecimal payPrice = webSocketVO.getPrice();
        BigDecimal balance = sysUser.getBalance().subtract(payPrice);
        if (balance.compareTo(payPrice) < 0) {//余额不足
            return AjaxResult.error(MessageUtils.message("prt.usr.balance.insufficient"));
        }
        Date date = new Date();
        PrtEqp eqp = prtEqpService.selectPrtEqpByEqpName(webSocketVO.getEqpName());

        //创建一条打印记录
        PrtPrintLog prtPrintLog = new PrtPrintLog();
        prtPrintLog.setPrintLogId(StringUtils.getUUID());
        prtPrintLog.setUser(sysUser.getUserId());
        prtPrintLog.setUserName(sysUser.getUserName());
        prtPrintLog.setUserTime(date);
        prtPrintLog.setEqpName(webSocketVO.getEqpName());
        prtPrintLog.setEqpId(eqp.getEqpId());
        prtPrintLog.setAddress(eqp.getAddress());
        prtPrintLog.setOrgId(eqp.getOrgId());
        prtPrintLog.setOrgName(eqp.getOrgName());
        prtPrintLog.setDocId(webSocketVO.getDocId());
        prtPrintLog.setDocName(webSocketVO.getFileName());
        if (webSocketVO.getColor().equals(1)){
            prtPrintLog.setIsColour(1);
            prtPrintLog.setIsBw(0);
        }else{
            prtPrintLog.setIsColour(0);
            prtPrintLog.setIsBw(1);
        }
        prtPrintLog.setIsPhoto(0);
        prtPrintLog.setIsDuplex(webSocketVO.getSide());
        prtPrintLog.setPaperType(webSocketVO.getMedia().toString());
        prtPrintLog.setPaperNum(Long.valueOf(webSocketVO.getCopies()));
        prtPrintLog.setPayPrice(payPrice);
        prtPrintLog.setPrintPrice(payPrice);
        prtPrintLog.setCouponId("0");
        prtPrintLog.setCouponName("无优惠");
        prtPrintLogService.insertPrtPrintLog(prtPrintLog);

        //创建一条消费订单记录
        PrtEpLog prtEpLog = new PrtEpLog();
        prtEpLog.setEpLogId(com.ruoyi.common.utils.StringUtils.getUUID());
        prtEpLog.setUser(sysUser.getUserId());
        prtEpLog.setUserName(sysUser.getUserName());
        prtEpLog.setUserTime(date);
        prtEpLog.setFundType("充值");
        prtEpLog.setFundDirection(0);
        prtEpLog.setPrice(payPrice);
        iPrtEpLogService.insertPrtEpLog(prtEpLog);

        //更新用户金额
        sysUser.setBalance(balance);
        SecurityUtils.getLoginUser().setUser(sysUser);
        int count = sysUserService.updateBalance(sysUser.getUserId(), balance);
        if (count > 0){
            return AjaxResult.success();
        }
        return AjaxResult.error(MessageUtils.message("prt.printer.balance.deduct.fail"));
    }

    @Override
    public AjaxResult calcPrice(WebSocketVO params) {
        PrtEqp eqp = prtEqpService.selectPrtEqpByEqpName(params.getEqpName());
        String priceModeId = eqp.getPriceModeId();
        PrtPriceMode priceMode = prtPriceModeService.selectPrtPriceModeById(priceModeId);
        //2.计算原始价格
        //打印页数
        int pageNum = params.getPage().split(",").length;
        //单张价格
        BigDecimal price;
        if (params.getColor() == 0) {
            if (params.getSide() == 0) {
                //黑白单面
                price = priceMode.getBwSinglePrice();
            } else {
                //黑白双面
                price = priceMode.getBwDuplexPrice();
            }
        } else {
            if (params.getSide() == 0) {
                //黑白单面
                price = priceMode.getColourSinglePrice();
            } else {
                //黑白双面
                price = priceMode.getColourDuplexPrice();
            }
        }
        BigDecimal originalPrice = price.multiply(BigDecimal.valueOf(pageNum));
        PrtCouponVO couponVO = new PrtCouponVO();
        Long userId = params.getUserId();
        //3.计算优惠价格
        String couponId = params.getCouponId();
        if (StringUtils.isNotEmpty(couponId)) {
            //计算优惠价格
            AjaxResult couponResult = prtCouponService.calcDiscountedPrice(originalPrice, couponId, eqp.getOrgId(), userId, "打印");
            if (couponResult.isError()) {
                return couponResult;
            }
            PrtCouponVO resultData = (PrtCouponVO) couponResult.getData();
            BeanUtils.copyProperties(resultData, couponVO);
        } else {
            couponVO.setPayPrice(originalPrice);
            couponVO.setOriginalPrice(originalPrice);
            couponVO.setIsUsed(false);
            couponVO.setEpqName(params.getEqpName());
            couponVO.setPrice(BigDecimal.ZERO);
        }
        couponVO.setPageNum(pageNum);
        couponVO.setOncePrice(price);
        return AjaxResult.success(couponVO);
    }

}
